package com.atguigu.tingshu.user.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.util.MongoUtil;
import com.atguigu.tingshu.model.user.UserListenProcess;
import com.atguigu.tingshu.user.service.UserListenProcessService;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.atguigu.tingshu.vo.user.UserListenProcessVo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@SuppressWarnings({"all"})
public class UserListenProcessServiceImpl implements UserListenProcessService {

	@Autowired
	private MongoTemplate mongoTemplate;
	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private RabbitService rabbitService;


	/**
	 * 获取声音的上次跳出时间
	 * @param trackId 声音的id
	 * @param userId
	 * @return
	 */
	@Override
	public UserListenProcess getTrackBreakSecond(Long trackId, Long userId) {

		Query query = new Query();
		//添加条件
		query.addCriteria(Criteria.where("userId").is(userId).and("trackId").is(trackId));
		UserListenProcess userListenProcess = mongoTemplate.findOne(query, UserListenProcess.class, MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId));
		if(userListenProcess !=null){
			//用户非第一次观看
			return  userListenProcess;
		}
		return null;

	}


	/**
	 *更新播放进度
	 * @param userListenProcessVo 条件
	 * @return
	 */
	@Override
	public void updateListenProcess(Long userId, UserListenProcessVo userListenProcessVo) {

		Query query = new Query();
		//条件
		query.addCriteria(Criteria.where("userId").is(userId).and("trackId").is(userListenProcessVo.getTrackId()));
		//防止设置查询第一条记录(避免小程序暂停后恢复播放将积压更新进度请求并发发起，导致新增多条播放进度)4
		query.with(Sort.by(Sort.Direction.DESC,"updateTime"));
		query.limit(1);
		UserListenProcess userListenProcess = mongoTemplate.findOne(query, UserListenProcess.class, MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId));
		if(userListenProcess==null){
			//用户第一次更新
			 userListenProcess = new UserListenProcess();
			userListenProcess.setUserId(userId);
			userListenProcess.setTrackId(userListenProcessVo.getTrackId());
			userListenProcess.setAlbumId(userListenProcessVo.getAlbumId());
			userListenProcess.setBreakSecond(userListenProcessVo.getBreakSecond());
			userListenProcess.setIsShow(1);
			userListenProcess.setCreateTime(new Date());
			userListenProcess.setUpdateTime(new Date());

		}else {
			//只更新时间
			userListenProcess.setBreakSecond(userListenProcessVo.getBreakSecond());
			userListenProcess.setUpdateTime(new Date());
		}

		mongoTemplate.save(userListenProcess,MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId));

		//更新播放量
		/**
		 * 1、发送rabbit 消息队列
		 * 2、利用redis的分布式锁 保障消息只执行一次  过期时间为1天
		 * 3、rabbit消息加事务 重试机制
		 */
		String key = RedisConstant.USER_TRACK_REPEAT_STAT_PREFIX + userId + ":" + userListenProcessVo.getTrackId();
		long ttl = DateUtil.endOfDay(new Date()).getTime() - System.currentTimeMillis();

		Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, userListenProcessVo.getTrackId(), ttl, TimeUnit.MILLISECONDS);
		if(flag){
			//线程拿到锁
			TrackStatMqVo trackStatMqVo = new TrackStatMqVo();
			trackStatMqVo.setBusinessNo(UUID.randomUUID().toString().replaceAll("-",""));
			trackStatMqVo.setAlbumId(userListenProcessVo.getAlbumId());
			trackStatMqVo.setTrackId(userListenProcessVo.getTrackId());
			trackStatMqVo.setStatType(SystemConstant.TRACK_STAT_PLAY); //播放量
			trackStatMqVo.setCount(1);
			//类型要转成JSON类型
			rabbitService.sendMessage(MqConst.EXCHANGE_TRACK , MqConst.ROUTING_TRACK_STAT_UPDATE, JSON.toJSONString(trackStatMqVo));

		}

	}
}
